package com.study.crypto.basic.gb.util;

import com.study.crypto.basic.utils.SM2Utils;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.pqc.math.linearalgebra.LittleEndianConversions;
import org.bouncycastle.util.BigIntegers;

import java.io.IOException;

/**
 * @author Songjin
 * @since 2021-06-20 17:00
 */
public final class SymKeyEncUtil {
    
    private SymKeyEncUtil() {
    }
    
    /**
     * 将 sm2 加密结构组装成 gmt 0018-2012 标准中的 ECC 加密数据结构，返回 base64 编码字符串
     * @param encrypted sm2 加密字节数据
     * @return 对称密钥封装
     * @throws IOException 异常
     */
    public static String capsulateSymKeyEnc(byte[] encrypted) throws IOException {
        ASN1EncodableVector vector = SM2Utils.decapsulateCipher(encrypted);
        byte[] x = BigIntegers.asUnsignedByteArray(((ASN1Integer) vector.get(0)).getPositiveValue());
        byte[] y = BigIntegers.asUnsignedByteArray(((ASN1Integer) vector.get(1)).getPositiveValue());
        byte[] hash = ((DEROctetString)vector.get(2)).getOctets();
        byte[] ciphertext = ((DEROctetString)vector.get(3)).getOctets();
        byte[] length = LittleEndianConversions.I2OSP(ciphertext.length);
    
        byte[] bytes = new byte[180];
        System.arraycopy(x, 0, bytes, 32, 32);
        System.arraycopy(y, 0, bytes, 96, 32);
        System.arraycopy(hash, 0, bytes, 128, 32);
        System.arraycopy(length, 0, bytes, 160, length.length);
        System.arraycopy(ciphertext, 0, bytes, 164, ciphertext.length);
        return Base64.encodeBase64String(bytes);
    }
}
